package com.cskaoyan.javase.oop3._0abstract._2exercise;

/**
 * 编码练习
 * 公司正在开发一套员工管理系统，需要对公司内部存在的员工进行管理
 * 公司将员工分为三类，普通员工负责杂项工作，程序员负责技术开发，经理负责统筹规划
 * 普通员工包含3个属性：姓名、工号以及工资，行为是工作
 * 程序员包含3个属性：姓名、工号以及工资，行为是工作和加班（overtime work）
 * 经理包含4个属性：姓名、工号、工资以及奖金（bonus），行为是工作
 * 请使用所学的知识设计该员工系统
 *
 * 使用普通员工类作为父类勉强可以实现需求,但是这么设计不好
 * 最好单独创建一个抽象的员工类,作为顶层父类
 * 顶层父类:AbstractStaff
 * 子类:
 *      普通员工:NormalStaff
 *      程序员:Coder
 *      经理:Manager
 *
 * 要求类中提供必要的方法进行属性访问（description）
 *
 *
 * 抽象类的作用是：做为继承体系中的顶层父类、祖先类而存在的。说白了所有继承了该抽象类的对象，都应该是一个该抽象类的对象。比如我定义了一个抽象的Person类，那么Student、Teacher等继承它是没问题的，但是让一个Cat继承就不行了（即便有成员可以复用）。只要是继承，就必须考虑"is-a"关系。
 * @since 14:26
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*AbstractStaff as;
        as = new NormalStaff();
        as.work();
        as = new Coder();
        as.work();
        // 访问Coder独有的方法,需要强转,需要用instanceof判断
        if (as instanceof Coder) {
            // 能够强转
            Coder coder = (Coder) as;
            coder.overtimeWork();
        }
        as = new Manager();
        as.work();*/

        // 创建对象,测试
        NormalStaff ns = new NormalStaff("张三", 1, 10000);
        ns.printStaff();
        Coder c = new Coder("李四", 2, 20000);
        c.printStaff();
        Manager m = new Manager("王二", 3, 30000, 100000);
        m.printStaff();

    }
}

// 抽象父类
abstract class AbstractStaff {
    private String name;
    private int id;
    private double salary;

    // 构造方法

    public AbstractStaff() {
    }

    public AbstractStaff(String name, int id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    // 抽象方法
    public abstract void work();

    // 打印属性
    public void printStaff() {
        System.out.println("id为" + id + "的员工,他的名字是:" + name + ",他的工资是:" + salary);
    }

    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }

    public double getSalary() {
        return salary;
    }
}

// 具体子类
class NormalStaff extends AbstractStaff {
    @Override
    public void work() {
        System.out.println("我负责杂项工作!");
    }

    public NormalStaff() {
    }

    public NormalStaff(String name, int id, double salary) {
        super(name, id, salary);
    }
}

class Coder extends AbstractStaff {
    @Override
    public void work() {
        System.out.println("我负责技术开发!");
    }

    public void overtimeWork() {
        System.out.println("我996,我秃了,我也变强了!");
    }

    public Coder() {
    }

    public Coder(String name, int id, double salary) {
        super(name, id, salary);
    }
}

class Manager extends AbstractStaff {

    private double bonus;

    @Override
    public void work() {
        System.out.println("我负责统筹规划!");
    }

    public Manager() {
    }

    public Manager(String name, int id, double salary, double bonus) {
        super(name, id, salary);
        this.bonus = bonus;
    }

    // 重写printStaff方法,因为有独有属性bonus
    @Override
    public void printStaff() {
        System.out.println("id为" + getId() + "的员工,他的名字是:" + getName() + ",他的工资是:" + (getSalary() + bonus));

    }
}